f594065
[xen.git] /
1 /******************************************************************************
2  * arch/x86/pv/emul-priv-op.c
3  *
4  * Emulate privileged instructions for PV guests
5  *
6  * Modifications to Linux original are copyright (c) 2002-2004, K A Fraser
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; If not, see <http://www.gnu.org/licenses/>.
20  */
21
22 #include <xen/errno.h>
23 #include <xen/event.h>
24 #include <xen/guest_access.h>
25 #include <xen/iocap.h>
26 #include <xen/spinlock.h>
27 #include <xen/trace.h>
28
29 #include <asm/amd.h>
30 #include <asm/apic.h>
31 #include <asm/debugreg.h>
32 #include <asm/hpet.h>
33 #include <asm/hypercall.h>
34 #include <asm/mc146818rtc.h>
35 #include <asm/p2m.h>
36 #include <asm/pv/domain.h>
37 #include <asm/pv/traps.h>
38 #include <asm/shared.h>
39 #include <asm/traps.h>
40 #include <asm/x86_emulate.h>
41
42 #include <xsm/xsm.h>
43
44 #include "../x86_64/mmconfig.h"
45 #include "emulate.h"
46 #include "mm.h"
47
48 struct priv_op_ctxt {
49     struct x86_emulate_ctxt ctxt;
50     struct {
51         unsigned long base, limit;
52     } cs;
53     char *io_emul_stub;
54     unsigned int bpmatch;
55 };
56
57 /* I/O emulation support. Helper routines for, and type of, the stack stub. */
58 void host_to_guest_gpr_switch(struct cpu_user_regs *);
59 unsigned long guest_to_host_gpr_switch(unsigned long);
60
61 typedef void io_emul_stub_t(struct cpu_user_regs *);
62
63 static io_emul_stub_t *io_emul_stub_setup(struct priv_op_ctxt *ctxt, u8 opcode,
64                                           unsigned int port, unsigned int bytes)
65 {
66     struct stubs *this_stubs = &this_cpu(stubs);
67     unsigned long stub_va = this_stubs->addr + STUB_BUF_SIZE / 2;
68     long disp;
69     bool use_quirk_stub = false;
70
71     if ( !ctxt->io_emul_stub )
72         ctxt->io_emul_stub =
73             map_domain_page(_mfn(this_stubs->mfn)) + (stub_va & ~PAGE_MASK);
74
75     /* call host_to_guest_gpr_switch */
76     ctxt->io_emul_stub[0] = 0xe8;
77     disp = (long)host_to_guest_gpr_switch - (stub_va + 5);
78     BUG_ON((int32_t)disp != disp);
79     *(int32_t *)&ctxt->io_emul_stub[1] = disp;
80
81     if ( unlikely(ioemul_handle_quirk) )
82         use_quirk_stub = ioemul_handle_quirk(opcode, &ctxt->io_emul_stub[5],
83                                              ctxt->ctxt.regs);
84
85     if ( !use_quirk_stub )
86     {
87         /* data16 or nop */
88         ctxt->io_emul_stub[5] = (bytes != 2) ? 0x90 : 0x66;
89         /* <io-access opcode> */
90         ctxt->io_emul_stub[6] = opcode;
91         /* imm8 or nop */
92         ctxt->io_emul_stub[7] = !(opcode & 8) ? port : 0x90;
93         /* ret (jumps to guest_to_host_gpr_switch) */
94         ctxt->io_emul_stub[8] = 0xc3;
95     }
96
97     BUILD_BUG_ON(STUB_BUF_SIZE / 2 < MAX(9, /* Default emul stub */
98                                          5 + IOEMUL_QUIRK_STUB_BYTES));
99
100     /* Handy function-typed pointer to the stub. */
101     return (void *)stub_va;
102 }
103
104
105 /* Perform IOPL check between the vcpu's shadowed IOPL, and the assumed cpl. */
106 static bool iopl_ok(const struct vcpu *v, const struct cpu_user_regs *regs)
107 {
108     unsigned int cpl = guest_kernel_mode(v, regs) ?
109         (VM_ASSIST(v->domain, architectural_iopl) ? 0 : 1) : 3;
110
111     ASSERT((v->arch.pv.iopl & ~X86_EFLAGS_IOPL) == 0);
112
113     return IOPL(cpl) <= v->arch.pv.iopl;
114 }
115
116 /* Has the guest requested sufficient permission for this I/O access? */
117 static bool guest_io_okay(unsigned int port, unsigned int bytes,
118                           struct vcpu *v, struct cpu_user_regs *regs)
119 {
120     /* If in user mode, switch to kernel mode just to read I/O bitmap. */
121     const bool user_mode = !(v->arch.flags & TF_kernel_mode);
122
123     if ( iopl_ok(v, regs) )
124         return true;
125
126     if ( (port + bytes) <= v->arch.pv.iobmp_limit )
127     {
128         union { uint8_t bytes[2]; uint16_t mask; } x;
129
130         /*
131          * Grab permission bytes from guest space. Inaccessible bytes are
132          * read as 0xff (no access allowed).
133          */
134         if ( user_mode )
135             toggle_guest_pt(v);
136
137         switch ( __copy_from_guest_offset(x.bytes, v->arch.pv.iobmp,
138                                           port>>3, 2) )
139         {
140         default: x.bytes[0] = ~0;
141             /* fallthrough */
142         case 1:  x.bytes[1] = ~0;
143             /* fallthrough */
144         case 0:  break;
145         }
146
147         if ( user_mode )
148             toggle_guest_pt(v);
149
150         if ( (x.mask & (((1 << bytes) - 1) << (port & 7))) == 0 )
151             return true;
152     }
153
154     return false;
155 }
156
157 /* Has the administrator granted sufficient permission for this I/O access? */
158 static bool admin_io_okay(unsigned int port, unsigned int bytes,
159                           const struct domain *d)
160 {
161     /*
162      * Port 0xcf8 (CONFIG_ADDRESS) is only visible for DWORD accesses.
163      * We never permit direct access to that register.
164      */
165     if ( (port == 0xcf8) && (bytes == 4) )
166         return false;
167
168     /* We also never permit direct access to the RTC/CMOS registers. */
169     if ( ((port & ~1) == RTC_PORT(0)) )
170         return false;
171
172     return ioports_access_permitted(d, port, port + bytes - 1);
173 }
174
175 static bool pci_cfg_ok(struct domain *currd, unsigned int start,
176                        unsigned int size, uint32_t *write)
177 {
178     uint32_t machine_bdf;
179
180     if ( !is_hardware_domain(currd) )
181         return false;
182
183     if ( !CF8_ENABLED(currd->arch.pci_cf8) )
184         return true;
185
186     machine_bdf = CF8_BDF(currd->arch.pci_cf8);
187     if ( write )
188     {
189         const unsigned long *ro_map = pci_get_ro_map(0);
190
191         if ( ro_map && test_bit(machine_bdf, ro_map) )
192             return false;
193     }
194     start |= CF8_ADDR_LO(currd->arch.pci_cf8);
195     /* AMD extended configuration space access? */
196     if ( CF8_ADDR_HI(currd->arch.pci_cf8) &&
197          boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
198          boot_cpu_data.x86 >= 0x10 && boot_cpu_data.x86 <= 0x17 )
199     {
200         uint64_t msr_val;
201
202         if ( rdmsr_safe(MSR_AMD64_NB_CFG, msr_val) )
203             return false;
204         if ( msr_val & (1ULL << AMD64_NB_CFG_CF8_EXT_ENABLE_BIT) )
205             start |= CF8_ADDR_HI(currd->arch.pci_cf8);
206     }
207
208     return !write ?
209            xsm_pci_config_permission(XSM_HOOK, currd, machine_bdf,
210                                      start, start + size - 1, 0) == 0 :
211            pci_conf_write_intercept(0, machine_bdf, start, size, write) >= 0;
212 }
213
214 static uint32_t guest_io_read(unsigned int port, unsigned int bytes,
215                               struct domain *currd)
216 {
217     uint32_t data = 0;
218     unsigned int shift = 0;
219
220     if ( admin_io_okay(port, bytes, currd) )
221     {
222         switch ( bytes )
223         {
224         case 1: return inb(port);
225         case 2: return inw(port);
226         case 4: return inl(port);
227         }
228     }
229
230     while ( bytes != 0 )
231     {
232         unsigned int size = 1;
233         uint32_t sub_data = ~0;
234
235         if ( (port == 0x42) || (port == 0x43) || (port == 0x61) )
236         {
237             sub_data = pv_pit_handler(port, 0, 0);
238         }
239         else if ( port == RTC_PORT(0) )
240         {
241             sub_data = currd->arch.cmos_idx;
242         }
243         else if ( (port == RTC_PORT(1)) &&
244                   ioports_access_permitted(currd, RTC_PORT(0), RTC_PORT(1)) )
245         {
246             unsigned long flags;
247
248             spin_lock_irqsave(&rtc_lock, flags);
249             outb(currd->arch.cmos_idx & 0x7f, RTC_PORT(0));
250             sub_data = inb(RTC_PORT(1));
251             spin_unlock_irqrestore(&rtc_lock, flags);
252         }
253         else if ( (port == 0xcf8) && (bytes == 4) )
254         {
255             size = 4;
256             sub_data = currd->arch.pci_cf8;
257         }
258         else if ( (port & 0xfffc) == 0xcfc )
259         {
260             size = min(bytes, 4 - (port & 3));
261             if ( size == 3 )
262                 size = 2;
263             if ( pci_cfg_ok(currd, port & 3, size, NULL) )
264                 sub_data = pci_conf_read(currd->arch.pci_cf8, port & 3, size);
265         }
266
267         if ( size == 4 )
268             return sub_data;
269
270         data |= (sub_data & ((1u << (size * 8)) - 1)) << shift;
271         shift += size * 8;
272         port += size;
273         bytes -= size;
274     }
275
276     return data;
277 }
278
279 static unsigned int check_guest_io_breakpoint(struct vcpu *v,
280                                               unsigned int port,
281                                               unsigned int len)
282 {
283     unsigned int width, i, match = 0;
284     unsigned long start;
285
286     if ( !v->arch.pv.dr7_emul || !(v->arch.pv.ctrlreg[4] & X86_CR4_DE) )
287         return 0;
288
289     for ( i = 0; i < 4; i++ )
290     {
291         if ( !(v->arch.pv.dr7_emul & (3 << (i * DR_ENABLE_SIZE))) )
292             continue;
293
294         start = v->arch.dr[i];
295         width = 0;
296
297         switch ( (v->arch.dr7 >>
298                   (DR_CONTROL_SHIFT + i * DR_CONTROL_SIZE)) & 0xc )
299         {
300         case DR_LEN_1: width = 1; break;
301         case DR_LEN_2: width = 2; break;
302         case DR_LEN_4: width = 4; break;
303         case DR_LEN_8: width = 8; break;
304         }
305
306         if ( (start < (port + len)) && ((start + width) > port) )
307             match |= 1u << i;
308     }
309
310     return match;
311 }
312
313 static int read_io(unsigned int port, unsigned int bytes,
314                    unsigned long *val, struct x86_emulate_ctxt *ctxt)
315 {
316     struct priv_op_ctxt *poc = container_of(ctxt, struct priv_op_ctxt, ctxt);
317     struct vcpu *curr = current;
318     struct domain *currd = current->domain;
319
320     /* INS must not come here. */
321     ASSERT((ctxt->opcode & ~9) == 0xe4);
322
323     if ( !guest_io_okay(port, bytes, curr, ctxt->regs) )
324         return X86EMUL_UNHANDLEABLE;
325
326     poc->bpmatch = check_guest_io_breakpoint(curr, port, bytes);
327
328     if ( admin_io_okay(port, bytes, currd) )
329     {
330         io_emul_stub_t *io_emul =
331             io_emul_stub_setup(poc, ctxt->opcode, port, bytes);
332
333         io_emul(ctxt->regs);
334         return X86EMUL_DONE;
335     }
336
337     *val = guest_io_read(port, bytes, currd);
338
339     return X86EMUL_OKAY;
340 }
341
342 static void guest_io_write(unsigned int port, unsigned int bytes,
343                            uint32_t data, struct domain *currd)
344 {
345     if ( admin_io_okay(port, bytes, currd) )
346     {
347         switch ( bytes )
348         {
349         case 1:
350             outb((uint8_t)data, port);
351             if ( amd_acpi_c1e_quirk )
352                 amd_check_disable_c1e(port, (uint8_t)data);
353             break;
354         case 2:
355             outw((uint16_t)data, port);
356             break;
357         case 4:
358             outl(data, port);
359             break;
360         }
361         return;
362     }
363
364     while ( bytes != 0 )
365     {
366         unsigned int size = 1;
367
368         if ( (port == 0x42) || (port == 0x43) || (port == 0x61) )
369         {
370             pv_pit_handler(port, (uint8_t)data, 1);
371         }
372         else if ( port == RTC_PORT(0) )
373         {
374             currd->arch.cmos_idx = data;
375         }
376         else if ( (port == RTC_PORT(1)) &&
377                   ioports_access_permitted(currd, RTC_PORT(0), RTC_PORT(1)) )
378         {
379             unsigned long flags;
380
381             if ( pv_rtc_handler )
382                 pv_rtc_handler(currd->arch.cmos_idx & 0x7f, data);
383             spin_lock_irqsave(&rtc_lock, flags);
384             outb(currd->arch.cmos_idx & 0x7f, RTC_PORT(0));
385             outb(data, RTC_PORT(1));
386             spin_unlock_irqrestore(&rtc_lock, flags);
387         }
388         else if ( (port == 0xcf8) && (bytes == 4) )
389         {
390             size = 4;
391             currd->arch.pci_cf8 = data;
392         }
393         else if ( (port & 0xfffc) == 0xcfc )
394         {
395             size = min(bytes, 4 - (port & 3));
396             if ( size == 3 )
397                 size = 2;
398             if ( pci_cfg_ok(currd, port & 3, size, &data) )
399                 pci_conf_write(currd->arch.pci_cf8, port & 3, size, data);
400         }
401
402         if ( size == 4 )
403             return;
404
405         port += size;
406         bytes -= size;
407         data >>= size * 8;
408     }
409 }
410
411 static int write_io(unsigned int port, unsigned int bytes,
412                     unsigned long val, struct x86_emulate_ctxt *ctxt)
413 {
414     struct priv_op_ctxt *poc = container_of(ctxt, struct priv_op_ctxt, ctxt);
415     struct vcpu *curr = current;
416     struct domain *currd = current->domain;
417
418     /* OUTS must not come here. */
419     ASSERT((ctxt->opcode & ~9) == 0xe6);
420
421     if ( !guest_io_okay(port, bytes, curr, ctxt->regs) )
422         return X86EMUL_UNHANDLEABLE;
423
424     poc->bpmatch = check_guest_io_breakpoint(curr, port, bytes);
425
426     if ( admin_io_okay(port, bytes, currd) )
427     {
428         io_emul_stub_t *io_emul =
429             io_emul_stub_setup(poc, ctxt->opcode, port, bytes);
430
431         io_emul(ctxt->regs);
432         if ( (bytes == 1) && amd_acpi_c1e_quirk )
433             amd_check_disable_c1e(port, val);
434         return X86EMUL_DONE;
435     }
436
437     guest_io_write(port, bytes, val, currd);
438
439     return X86EMUL_OKAY;
440 }
441
442 static int read_segment(enum x86_segment seg,
443                         struct segment_register *reg,
444                         struct x86_emulate_ctxt *ctxt)
445 {
446     /* Check if this is an attempt to access the I/O bitmap. */
447     if ( seg == x86_seg_tr )
448     {
449         switch ( ctxt->opcode )
450         {
451         case 0x6c ... 0x6f: /* ins / outs */
452         case 0xe4 ... 0xe7: /* in / out (immediate port) */
453         case 0xec ... 0xef: /* in / out (port in %dx) */
454             /* Defer the check to priv_op_{read,write}_io(). */
455             return X86EMUL_DONE;
456         }
457     }
458
459     if ( ctxt->addr_size < 64 )
460     {
461         unsigned long limit;
462         unsigned int sel, ar;
463
464         switch ( seg )
465         {
466         case x86_seg_cs: sel = ctxt->regs->cs; break;
467         case x86_seg_ds: sel = read_sreg(ds);  break;
468         case x86_seg_es: sel = read_sreg(es);  break;
469         case x86_seg_fs: sel = read_sreg(fs);  break;
470         case x86_seg_gs: sel = read_sreg(gs);  break;
471         case x86_seg_ss: sel = ctxt->regs->ss; break;
472         default: return X86EMUL_UNHANDLEABLE;
473         }
474
475         if ( !pv_emul_read_descriptor(sel, current, &reg->base,
476                                       &limit, &ar, 0) )
477             return X86EMUL_UNHANDLEABLE;
478
479         reg->limit = limit;
480         reg->attr = ar >> 8;
481     }
482     else
483     {
484         switch ( seg )
485         {
486         default:
487             if ( !is_x86_user_segment(seg) )
488                 return X86EMUL_UNHANDLEABLE;
489             reg->base = 0;
490             break;
491         case x86_seg_fs:
492             reg->base = rdfsbase();
493             break;
494         case x86_seg_gs:
495             reg->base = rdgsbase();
496             break;
497         }
498
499         reg->limit = ~0U;
500
501         reg->attr = 0;
502         reg->type = _SEGMENT_WR >> 8;
503         if ( seg == x86_seg_cs )
504         {
505             reg->type |= _SEGMENT_CODE >> 8;
506             reg->l = 1;
507         }
508         else
509             reg->db = 1;
510         reg->s   = 1;
511         reg->dpl = 3;
512         reg->p   = 1;
513         reg->g   = 1;
514     }
515
516     /*
517      * For x86_emulate.c's mode_ring0() to work, fake a DPL of zero.
518      * Also do this for consistency for non-conforming code segments.
519      */
520     if ( (seg == x86_seg_ss ||
521           (seg == x86_seg_cs &&
522            !(reg->type & (_SEGMENT_EC >> 8)))) &&
523          guest_kernel_mode(current, ctxt->regs) )
524         reg->dpl = 0;
525
526     return X86EMUL_OKAY;
527 }
528
529 static int pv_emul_virt_to_linear(unsigned long base, unsigned long offset,
530                                   unsigned int bytes, unsigned long limit,
531                                   enum x86_segment seg,
532                                   struct x86_emulate_ctxt *ctxt,
533                                   unsigned long *addr)
534 {
535     int rc = X86EMUL_OKAY;
536
537     *addr = base + offset;
538
539     if ( ctxt->addr_size < 64 )
540     {
541         if ( limit < bytes - 1 || offset > limit - bytes + 1 )
542             rc = X86EMUL_EXCEPTION;
543         *addr = (uint32_t)*addr;
544     }
545     else if ( !__addr_ok(*addr) )
546         rc = X86EMUL_EXCEPTION;
547
548     if ( unlikely(rc == X86EMUL_EXCEPTION) )
549         x86_emul_hw_exception(seg != x86_seg_ss ? TRAP_gp_fault
550                                                 : TRAP_stack_error,
551                               0, ctxt);
552
553     return rc;
554 }
555
556 static int rep_ins(uint16_t port,
557                    enum x86_segment seg, unsigned long offset,
558                    unsigned int bytes_per_rep, unsigned long *reps,
559                    struct x86_emulate_ctxt *ctxt)
560 {
561     struct priv_op_ctxt *poc = container_of(ctxt, struct priv_op_ctxt, ctxt);
562     struct vcpu *curr = current;
563     struct domain *currd = current->domain;
564     unsigned long goal = *reps;
565     struct segment_register sreg;
566     int rc;
567
568     ASSERT(seg == x86_seg_es);
569
570     *reps = 0;
571
572     if ( !guest_io_okay(port, bytes_per_rep, curr, ctxt->regs) )
573         return X86EMUL_UNHANDLEABLE;
574
575     rc = read_segment(x86_seg_es, &sreg, ctxt);
576     if ( rc != X86EMUL_OKAY )
577         return rc;
578
579     if ( !sreg.p )
580         return X86EMUL_UNHANDLEABLE;
581     if ( !sreg.s ||
582          (sreg.type & (_SEGMENT_CODE >> 8)) ||
583          !(sreg.type & (_SEGMENT_WR >> 8)) )
584     {
585         x86_emul_hw_exception(TRAP_gp_fault, 0, ctxt);
586         return X86EMUL_EXCEPTION;
587     }
588
589     poc->bpmatch = check_guest_io_breakpoint(curr, port, bytes_per_rep);
590
591     while ( *reps < goal )
592     {
593         unsigned int data = guest_io_read(port, bytes_per_rep, currd);
594         unsigned long addr;
595
596         rc = pv_emul_virt_to_linear(sreg.base, offset, bytes_per_rep,
597                                     sreg.limit, x86_seg_es, ctxt, &addr);
598         if ( rc != X86EMUL_OKAY )
599             return rc;
600
601         if ( (rc = __copy_to_user((void *)addr, &data, bytes_per_rep)) != 0 )
602         {
603             x86_emul_pagefault(PFEC_write_access,
604                                addr + bytes_per_rep - rc, ctxt);
605             return X86EMUL_EXCEPTION;
606         }
607
608         ++*reps;
609
610         if ( poc->bpmatch || hypercall_preempt_check() )
611             break;
612
613         /* x86_emulate() clips the repetition count to ensure we don't wrap. */
614         if ( unlikely(ctxt->regs->eflags & X86_EFLAGS_DF) )
615             offset -= bytes_per_rep;
616         else
617             offset += bytes_per_rep;
618     }
619
620     return X86EMUL_OKAY;
621 }
622
623 static int rep_outs(enum x86_segment seg, unsigned long offset,
624                     uint16_t port,
625                     unsigned int bytes_per_rep, unsigned long *reps,
626                     struct x86_emulate_ctxt *ctxt)
627 {
628     struct priv_op_ctxt *poc = container_of(ctxt, struct priv_op_ctxt, ctxt);
629     struct vcpu *curr = current;
630     struct domain *currd = current->domain;
631     unsigned long goal = *reps;
632     struct segment_register sreg;
633     int rc;
634
635     *reps = 0;
636
637     if ( !guest_io_okay(port, bytes_per_rep, curr, ctxt->regs) )
638         return X86EMUL_UNHANDLEABLE;
639
640     rc = read_segment(seg, &sreg, ctxt);
641     if ( rc != X86EMUL_OKAY )
642         return rc;
643
644     if ( !sreg.p )
645         return X86EMUL_UNHANDLEABLE;
646     if ( !sreg.s ||
647          ((sreg.type & (_SEGMENT_CODE >> 8)) &&
648           !(sreg.type & (_SEGMENT_WR >> 8))) )
649     {
650         x86_emul_hw_exception(seg != x86_seg_ss ? TRAP_gp_fault
651                                                 : TRAP_stack_error,
652                               0, ctxt);
653         return X86EMUL_EXCEPTION;
654     }
655
656     poc->bpmatch = check_guest_io_breakpoint(curr, port, bytes_per_rep);
657
658     while ( *reps < goal )
659     {
660         unsigned int data = 0;
661         unsigned long addr;
662
663         rc = pv_emul_virt_to_linear(sreg.base, offset, bytes_per_rep,
664                                     sreg.limit, seg, ctxt, &addr);
665         if ( rc != X86EMUL_OKAY )
666             return rc;
667
668         if ( (rc = __copy_from_user(&data, (void *)addr, bytes_per_rep)) != 0 )
669         {
670             x86_emul_pagefault(0, addr + bytes_per_rep - rc, ctxt);
671             return X86EMUL_EXCEPTION;
672         }
673
674         guest_io_write(port, bytes_per_rep, data, currd);
675
676         ++*reps;
677
678         if ( poc->bpmatch || hypercall_preempt_check() )
679             break;
680
681         /* x86_emulate() clips the repetition count to ensure we don't wrap. */
682         if ( unlikely(ctxt->regs->eflags & X86_EFLAGS_DF) )
683             offset -= bytes_per_rep;
684         else
685             offset += bytes_per_rep;
686     }
687
688     return X86EMUL_OKAY;
689 }
690
691 static int read_cr(unsigned int reg, unsigned long *val,
692                    struct x86_emulate_ctxt *ctxt)
693 {
694     const struct vcpu *curr = current;
695
696     switch ( reg )
697     {
698     case 0: /* Read CR0 */
699         *val = (read_cr0() & ~X86_CR0_TS) | curr->arch.pv.ctrlreg[0];
700         return X86EMUL_OKAY;
701
702     case 2: /* Read CR2 */
703     case 4: /* Read CR4 */
704         *val = curr->arch.pv.ctrlreg[reg];
705         return X86EMUL_OKAY;
706
707     case 3: /* Read CR3 */
708     {
709         const struct domain *currd = curr->domain;
710         mfn_t mfn;
711
712         if ( !is_pv_32bit_domain(currd) )
713         {
714             mfn = pagetable_get_mfn(curr->arch.guest_table);
715             *val = xen_pfn_to_cr3(mfn_to_gmfn(currd, mfn_x(mfn)));
716         }
717         else
718         {
719             l4_pgentry_t *pl4e =
720                 map_domain_page(pagetable_get_mfn(curr->arch.guest_table));
721
722             mfn = l4e_get_mfn(*pl4e);
723             unmap_domain_page(pl4e);
724             *val = compat_pfn_to_cr3(mfn_to_gmfn(currd, mfn_x(mfn)));
725         }
726         /* PTs should not be shared */
727         BUG_ON(page_get_owner(mfn_to_page(mfn)) == dom_cow);
728         return X86EMUL_OKAY;
729     }
730     }
731
732     return X86EMUL_UNHANDLEABLE;
733 }
734
735 static int write_cr(unsigned int reg, unsigned long val,
736                     struct x86_emulate_ctxt *ctxt)
737 {
738     struct vcpu *curr = current;
739
740     switch ( reg )
741     {
742     case 0: /* Write CR0 */
743         if ( (val ^ read_cr0()) & ~X86_CR0_TS )
744         {
745             gdprintk(XENLOG_WARNING,
746                      "Attempt to change unmodifiable CR0 flags\n");
747             break;
748         }
749         do_fpu_taskswitch(!!(val & X86_CR0_TS));
750         return X86EMUL_OKAY;
751
752     case 2: /* Write CR2 */
753         curr->arch.pv.ctrlreg[2] = val;
754         arch_set_cr2(curr, val);
755         return X86EMUL_OKAY;
756
757     case 3: /* Write CR3 */
758     {
759         struct domain *currd = curr->domain;
760         unsigned long gfn;
761         struct page_info *page;
762         int rc;
763
764         gfn = !is_pv_32bit_domain(currd)
765               ? xen_cr3_to_pfn(val) : compat_cr3_to_pfn(val);
766         page = get_page_from_gfn(currd, gfn, NULL, P2M_ALLOC);
767         if ( !page )
768             break;
769         rc = new_guest_cr3(page_to_mfn(page));
770         put_page(page);
771
772         switch ( rc )
773         {
774         case 0:
775             return X86EMUL_OKAY;
776         case -ERESTART: /* retry after preemption */
777             return X86EMUL_RETRY;
778         }
779         break;
780     }
781
782     case 4: /* Write CR4 */
783         /*
784          * If this write will disable FSGSBASE, refresh Xen's idea of the
785          * guest bases now that they can no longer change.
786          */
787         if ( (curr->arch.pv.ctrlreg[4] & X86_CR4_FSGSBASE) &&
788              !(val & X86_CR4_FSGSBASE) )
789         {
790             curr->arch.pv.fs_base = __rdfsbase();
791             curr->arch.pv.gs_base_kernel = __rdgsbase();
792         }
793
794         curr->arch.pv.ctrlreg[4] = pv_fixup_guest_cr4(curr, val);
795         write_cr4(pv_make_cr4(curr));
796         ctxt_switch_levelling(curr);
797         return X86EMUL_OKAY;
798     }
799
800     return X86EMUL_UNHANDLEABLE;
801 }
802
803 static inline uint64_t guest_misc_enable(uint64_t val)
804 {
805     val &= ~(MSR_IA32_MISC_ENABLE_PERF_AVAIL |
806              MSR_IA32_MISC_ENABLE_MONITOR_ENABLE);
807     val |= MSR_IA32_MISC_ENABLE_BTS_UNAVAIL |
808            MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL |
809            MSR_IA32_MISC_ENABLE_XTPR_DISABLE;
810     return val;
811 }
812
813 static inline bool is_cpufreq_controller(const struct domain *d)
814 {
815     return ((cpufreq_controller == FREQCTL_dom0_kernel) &&
816             is_hardware_domain(d));
817 }
818
819 static int read_msr(unsigned int reg, uint64_t *val,
820                     struct x86_emulate_ctxt *ctxt)
821 {
822     const struct vcpu *curr = current;
823     const struct domain *currd = curr->domain;
824     bool vpmu_msr = false;
825     int ret;
826
827     if ( (ret = guest_rdmsr(curr, reg, val)) != X86EMUL_UNHANDLEABLE )
828     {
829         if ( ret == X86EMUL_EXCEPTION )
830             x86_emul_hw_exception(TRAP_gp_fault, 0, ctxt);
831
832         return ret;
833     }
834
835     switch ( reg )
836     {
837         int rc;
838
839     case MSR_FS_BASE:
840         if ( is_pv_32bit_domain(currd) )
841             break;
842         *val = (read_cr4() & X86_CR4_FSGSBASE) ? __rdfsbase()
843                                                : curr->arch.pv.fs_base;
844         return X86EMUL_OKAY;
845
846     case MSR_GS_BASE:
847         if ( is_pv_32bit_domain(currd) )
848             break;
849         *val = (read_cr4() & X86_CR4_FSGSBASE) ? __rdgsbase()
850                                                : curr->arch.pv.gs_base_kernel;
851         return X86EMUL_OKAY;
852
853     case MSR_SHADOW_GS_BASE:
854         if ( is_pv_32bit_domain(currd) )
855             break;
856         *val = curr->arch.pv.gs_base_user;
857         return X86EMUL_OKAY;
858
859     case MSR_IA32_TSC:
860         *val = currd->arch.vtsc ? pv_soft_rdtsc(curr, ctxt->regs) : rdtsc();
861         return X86EMUL_OKAY;
862
863     case MSR_EFER:
864         /* Hide unknown bits, and unconditionally hide SVME from guests. */
865         *val = read_efer() & EFER_KNOWN_MASK & ~EFER_SVME;
866         /*
867          * Hide the 64-bit features from 32-bit guests.  SCE has
868          * vendor-dependent behaviour.
869          */
870         if ( is_pv_32bit_domain(currd) )
871             *val &= ~(EFER_LME | EFER_LMA |
872                       (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL
873                        ? EFER_SCE : 0));
874         return X86EMUL_OKAY;
875
876     case MSR_K7_FID_VID_CTL:
877     case MSR_K7_FID_VID_STATUS:
878     case MSR_K8_PSTATE_LIMIT:
879     case MSR_K8_PSTATE_CTRL:
880     case MSR_K8_PSTATE_STATUS:
881     case MSR_K8_PSTATE0:
882     case MSR_K8_PSTATE1:
883     case MSR_K8_PSTATE2:
884     case MSR_K8_PSTATE3:
885     case MSR_K8_PSTATE4:
886     case MSR_K8_PSTATE5:
887     case MSR_K8_PSTATE6:
888     case MSR_K8_PSTATE7:
889         if ( boot_cpu_data.x86_vendor != X86_VENDOR_AMD )
890             break;
891         if ( unlikely(is_cpufreq_controller(currd)) )
892             goto normal;
893         *val = 0;
894         return X86EMUL_OKAY;
895
896     case MSR_IA32_UCODE_REV:
897         BUILD_BUG_ON(MSR_IA32_UCODE_REV != MSR_AMD_PATCHLEVEL);
898         if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL )
899         {
900             if ( wrmsr_safe(MSR_IA32_UCODE_REV, 0) )
901                 break;
902             /* As documented in the SDM: Do a CPUID 1 here */
903             cpuid_eax(1);
904         }
905         goto normal;
906
907     case MSR_IA32_MISC_ENABLE:
908         rdmsrl(reg, *val);
909         *val = guest_misc_enable(*val);
910         return X86EMUL_OKAY;
911
912     case MSR_IA32_PERF_CAPABILITIES:
913         /* No extra capabilities are supported. */
914         *val = 0;
915         return X86EMUL_OKAY;
916
917     case MSR_P6_PERFCTR(0) ... MSR_P6_PERFCTR(7):
918     case MSR_P6_EVNTSEL(0) ... MSR_P6_EVNTSEL(3):
919     case MSR_CORE_PERF_FIXED_CTR0 ... MSR_CORE_PERF_FIXED_CTR2:
920     case MSR_CORE_PERF_FIXED_CTR_CTRL ... MSR_CORE_PERF_GLOBAL_OVF_CTRL:
921         if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL )
922         {
923             vpmu_msr = true;
924             /* fall through */
925     case MSR_AMD_FAM15H_EVNTSEL0 ... MSR_AMD_FAM15H_PERFCTR5:
926     case MSR_K7_EVNTSEL0 ... MSR_K7_PERFCTR3:
927             if ( vpmu_msr || (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) )
928             {
929                 if ( vpmu_do_rdmsr(reg, val) )
930                     break;
931                 return X86EMUL_OKAY;
932             }
933         }
934         /* fall through */
935     default:
936         rc = vmce_rdmsr(reg, val);
937         if ( rc < 0 )
938             break;
939         if ( rc )
940             return X86EMUL_OKAY;
941         /* fall through */
942     normal:
943         /* Everyone can read the MSR space. */
944         /* gdprintk(XENLOG_WARNING, "Domain attempted RDMSR %08x\n", reg); */
945         if ( rdmsr_safe(reg, *val) )
946             break;
947         return X86EMUL_OKAY;
948     }
949
950     return X86EMUL_UNHANDLEABLE;
951 }
952
953 static int write_msr(unsigned int reg, uint64_t val,
954                      struct x86_emulate_ctxt *ctxt)
955 {
956     struct vcpu *curr = current;
957     const struct domain *currd = curr->domain;
958     bool vpmu_msr = false;
959     int ret;
960
961     if ( (ret = guest_wrmsr(curr, reg, val)) != X86EMUL_UNHANDLEABLE )
962     {
963         if ( ret == X86EMUL_EXCEPTION )
964             x86_emul_hw_exception(TRAP_gp_fault, 0, ctxt);
965
966         return ret;
967     }
968
969     switch ( reg )
970     {
971         uint64_t temp;
972         int rc;
973
974     case MSR_FS_BASE:
975         if ( is_pv_32bit_domain(currd) || !is_canonical_address(val) )
976             break;
977         wrfsbase(val);
978         curr->arch.pv.fs_base = val;
979         return X86EMUL_OKAY;
980
981     case MSR_GS_BASE:
982         if ( is_pv_32bit_domain(currd) || !is_canonical_address(val) )
983             break;
984         wrgsbase(val);
985         curr->arch.pv.gs_base_kernel = val;
986         return X86EMUL_OKAY;
987
988     case MSR_SHADOW_GS_BASE:
989         if ( is_pv_32bit_domain(currd) || !is_canonical_address(val) )
990             break;
991         wrgsshadow(val);
992         curr->arch.pv.gs_base_user = val;
993         return X86EMUL_OKAY;
994
995     case MSR_K7_FID_VID_STATUS:
996     case MSR_K7_FID_VID_CTL:
997     case MSR_K8_PSTATE_LIMIT:
998     case MSR_K8_PSTATE_CTRL:
999     case MSR_K8_PSTATE_STATUS:
1000     case MSR_K8_PSTATE0:
1001     case MSR_K8_PSTATE1:
1002     case MSR_K8_PSTATE2:
1003     case MSR_K8_PSTATE3:
1004     case MSR_K8_PSTATE4:
1005     case MSR_K8_PSTATE5:
1006     case MSR_K8_PSTATE6:
1007     case MSR_K8_PSTATE7:
1008     case MSR_K8_HWCR:
1009         if ( boot_cpu_data.x86_vendor != X86_VENDOR_AMD )
1010             break;
1011         if ( likely(!is_cpufreq_controller(currd)) ||
1012              wrmsr_safe(reg, val) == 0 )
1013             return X86EMUL_OKAY;
1014         break;
1015
1016     case MSR_AMD64_NB_CFG:
1017         if ( boot_cpu_data.x86_vendor != X86_VENDOR_AMD ||
1018              boot_cpu_data.x86 < 0x10 || boot_cpu_data.x86 > 0x17 )
1019             break;
1020         if ( !is_hwdom_pinned_vcpu(curr) )
1021             return X86EMUL_OKAY;
1022         if ( (rdmsr_safe(MSR_AMD64_NB_CFG, temp) != 0) ||
1023              ((val ^ temp) & ~(1ULL << AMD64_NB_CFG_CF8_EXT_ENABLE_BIT)) )
1024             goto invalid;
1025         if ( wrmsr_safe(MSR_AMD64_NB_CFG, val) == 0 )
1026             return X86EMUL_OKAY;
1027         break;
1028
1029     case MSR_FAM10H_MMIO_CONF_BASE:
1030         if ( boot_cpu_data.x86_vendor != X86_VENDOR_AMD ||
1031              boot_cpu_data.x86 < 0x10 || boot_cpu_data.x86 > 0x17 )
1032             break;
1033         if ( !is_hwdom_pinned_vcpu(curr) )
1034             return X86EMUL_OKAY;
1035         if ( rdmsr_safe(MSR_FAM10H_MMIO_CONF_BASE, temp) != 0 )
1036             break;
1037         if ( (pci_probe & PCI_PROBE_MASK) == PCI_PROBE_MMCONF ?
1038              temp != val :
1039              ((temp ^ val) &
1040               ~(FAM10H_MMIO_CONF_ENABLE |
1041                 (FAM10H_MMIO_CONF_BUSRANGE_MASK <<
1042                  FAM10H_MMIO_CONF_BUSRANGE_SHIFT) |
1043                 ((u64)FAM10H_MMIO_CONF_BASE_MASK <<
1044                  FAM10H_MMIO_CONF_BASE_SHIFT))) )
1045             goto invalid;
1046         if ( wrmsr_safe(MSR_FAM10H_MMIO_CONF_BASE, val) == 0 )
1047             return X86EMUL_OKAY;
1048         break;
1049
1050     case MSR_IA32_UCODE_REV:
1051         if ( boot_cpu_data.x86_vendor != X86_VENDOR_INTEL )
1052             break;
1053         if ( !is_hwdom_pinned_vcpu(curr) )
1054             return X86EMUL_OKAY;
1055         if ( rdmsr_safe(reg, temp) )
1056             break;
1057         if ( val )
1058             goto invalid;
1059         return X86EMUL_OKAY;
1060
1061     case MSR_IA32_MISC_ENABLE:
1062         rdmsrl(reg, temp);
1063         if ( val != guest_misc_enable(temp) )
1064             goto invalid;
1065         return X86EMUL_OKAY;
1066
1067     case MSR_IA32_MPERF:
1068     case MSR_IA32_APERF:
1069         if ( !(boot_cpu_data.x86_vendor & (X86_VENDOR_INTEL | X86_VENDOR_AMD)) )
1070             break;
1071         if ( likely(!is_cpufreq_controller(currd)) ||
1072              wrmsr_safe(reg, val) == 0 )
1073             return X86EMUL_OKAY;
1074         break;
1075
1076     case MSR_IA32_PERF_CTL:
1077         if ( boot_cpu_data.x86_vendor != X86_VENDOR_INTEL )
1078             break;
1079         if ( likely(!is_cpufreq_controller(currd)) ||
1080              wrmsr_safe(reg, val) == 0 )
1081             return X86EMUL_OKAY;
1082         break;
1083
1084     case MSR_IA32_THERM_CONTROL:
1085     case MSR_IA32_ENERGY_PERF_BIAS:
1086         if ( boot_cpu_data.x86_vendor != X86_VENDOR_INTEL )
1087             break;
1088         if ( !is_hwdom_pinned_vcpu(curr) || wrmsr_safe(reg, val) == 0 )
1089             return X86EMUL_OKAY;
1090         break;
1091
1092     case MSR_P6_PERFCTR(0) ... MSR_P6_PERFCTR(7):
1093     case MSR_P6_EVNTSEL(0) ... MSR_P6_EVNTSEL(3):
1094     case MSR_CORE_PERF_FIXED_CTR0 ... MSR_CORE_PERF_FIXED_CTR2:
1095     case MSR_CORE_PERF_FIXED_CTR_CTRL ... MSR_CORE_PERF_GLOBAL_OVF_CTRL:
1096         if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL )
1097         {
1098             vpmu_msr = true;
1099     case MSR_AMD_FAM15H_EVNTSEL0 ... MSR_AMD_FAM15H_PERFCTR5:
1100     case MSR_K7_EVNTSEL0 ... MSR_K7_PERFCTR3:
1101             if ( vpmu_msr || (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) )
1102             {
1103                 if ( (vpmu_mode & XENPMU_MODE_ALL) &&
1104                      !is_hardware_domain(currd) )
1105                     return X86EMUL_OKAY;
1106
1107                 if ( vpmu_do_wrmsr(reg, val, 0) )
1108                     break;
1109                 return X86EMUL_OKAY;
1110             }
1111         }
1112         /* fall through */
1113     default:
1114         rc = vmce_wrmsr(reg, val);
1115         if ( rc < 0 )
1116             break;
1117         if ( rc )
1118             return X86EMUL_OKAY;
1119
1120         if ( (rdmsr_safe(reg, temp) != 0) || (val != temp) )
1121     invalid:
1122             gdprintk(XENLOG_WARNING,
1123                      "Domain attempted WRMSR %08x from 0x%016"PRIx64" to 0x%016"PRIx64"\n",
1124                      reg, temp, val);
1125         return X86EMUL_OKAY;
1126     }
1127
1128     return X86EMUL_UNHANDLEABLE;
1129 }
1130
1131 /* Name it differently to avoid clashing with wbinvd() */
1132 static int _wbinvd(struct x86_emulate_ctxt *ctxt)
1133 {
1134     /* Ignore the instruction if unprivileged. */
1135     if ( !cache_flush_permitted(current->domain) )
1136         /*
1137          * Non-physdev domain attempted WBINVD; ignore for now since
1138          * newer linux uses this in some start-of-day timing loops.
1139          */
1140         ;
1141     else
1142         wbinvd();
1143
1144     return X86EMUL_OKAY;
1145 }
1146
1147 int pv_emul_cpuid(uint32_t leaf, uint32_t subleaf,
1148                   struct cpuid_leaf *res, struct x86_emulate_ctxt *ctxt)
1149 {
1150     guest_cpuid(current, leaf, subleaf, res);
1151
1152     return X86EMUL_OKAY;
1153 }
1154
1155 static int validate(const struct x86_emulate_state *state,
1156                     struct x86_emulate_ctxt *ctxt)
1157 {
1158     switch ( ctxt->opcode )
1159     {
1160     case 0x6c ... 0x6f: /* ins / outs */
1161     case 0xe4 ... 0xe7: /* in / out (immediate port) */
1162     case 0xec ... 0xef: /* in / out (port in %dx) */
1163     case X86EMUL_OPC(0x0f, 0x06): /* clts */
1164     case X86EMUL_OPC(0x0f, 0x09): /* wbinvd */
1165     case X86EMUL_OPC(0x0f, 0x20) ...
1166          X86EMUL_OPC(0x0f, 0x23): /* mov to/from cr/dr */
1167     case X86EMUL_OPC(0x0f, 0x30): /* wrmsr */
1168     case X86EMUL_OPC(0x0f, 0x31): /* rdtsc */
1169     case X86EMUL_OPC(0x0f, 0x32): /* rdmsr */
1170     case X86EMUL_OPC(0x0f, 0xa2): /* cpuid */
1171         return X86EMUL_OKAY;
1172
1173     case 0xfa: case 0xfb: /* cli / sti */
1174         if ( !iopl_ok(current, ctxt->regs) )
1175             break;
1176         /*
1177          * This is just too dangerous to allow, in my opinion. Consider if the
1178          * caller then tries to reenable interrupts using POPF: we can't trap
1179          * that and we'll end up with hard-to-debug lockups. Fast & loose will
1180          * do for us. :-)
1181         vcpu_info(current, evtchn_upcall_mask) = (ctxt->opcode == 0xfa);
1182          */
1183         return X86EMUL_DONE;
1184
1185     case X86EMUL_OPC(0x0f, 0x01):
1186     {
1187         unsigned int modrm_rm, modrm_reg;
1188
1189         if ( x86_insn_modrm(state, &modrm_rm, &modrm_reg) != 3 ||
1190              (modrm_rm & 7) != 1 )
1191             break;
1192         switch ( modrm_reg & 7 )
1193         {
1194         case 2: /* xsetbv */
1195         case 7: /* rdtscp */
1196             return X86EMUL_OKAY;
1197         }
1198         break;
1199     }
1200     }
1201
1202     return X86EMUL_UNHANDLEABLE;
1203 }
1204
1205 static int insn_fetch(enum x86_segment seg,
1206                       unsigned long offset,
1207                       void *p_data,
1208                       unsigned int bytes,
1209                       struct x86_emulate_ctxt *ctxt)
1210 {
1211     const struct priv_op_ctxt *poc =
1212         container_of(ctxt, struct priv_op_ctxt, ctxt);
1213     unsigned int rc;
1214     unsigned long addr = poc->cs.base + offset;
1215
1216     ASSERT(seg == x86_seg_cs);
1217
1218     /* We don't mean to emulate any branches. */
1219     if ( !bytes )
1220         return X86EMUL_UNHANDLEABLE;
1221
1222     rc = pv_emul_virt_to_linear(poc->cs.base, offset, bytes, poc->cs.limit,
1223                                 x86_seg_cs, ctxt, &addr);
1224     if ( rc != X86EMUL_OKAY )
1225         return rc;
1226
1227     if ( (rc = __copy_from_user(p_data, (void *)addr, bytes)) != 0 )
1228     {
1229         /*
1230          * TODO: This should report PFEC_insn_fetch when goc->insn_fetch &&
1231          * cpu_has_nx, but we'd then need a "fetch" variant of
1232          * __copy_from_user() respecting NX, SMEP, and protection keys.
1233          */
1234         x86_emul_pagefault(0, addr + bytes - rc, ctxt);
1235         return X86EMUL_EXCEPTION;
1236     }
1237
1238     return X86EMUL_OKAY;
1239 }
1240
1241
1242 static const struct x86_emulate_ops priv_op_ops = {
1243     .insn_fetch          = insn_fetch,
1244     .read                = x86emul_unhandleable_rw,
1245     .validate            = validate,
1246     .read_io             = read_io,
1247     .write_io            = write_io,
1248     .rep_ins             = rep_ins,
1249     .rep_outs            = rep_outs,
1250     .read_segment        = read_segment,
1251     .read_cr             = read_cr,
1252     .write_cr            = write_cr,
1253     .read_dr             = x86emul_read_dr,
1254     .write_dr            = x86emul_write_dr,
1255     .write_xcr           = x86emul_write_xcr,
1256     .read_msr            = read_msr,
1257     .write_msr           = write_msr,
1258     .cpuid               = pv_emul_cpuid,
1259     .wbinvd              = _wbinvd,
1260 };
1261
1262 int pv_emulate_privileged_op(struct cpu_user_regs *regs)
1263 {
1264     struct vcpu *curr = current;
1265     struct domain *currd = curr->domain;
1266     struct priv_op_ctxt ctxt = {
1267         .ctxt.regs = regs,
1268         .ctxt.vendor = currd->arch.cpuid->x86_vendor,
1269         .ctxt.lma = !is_pv_32bit_domain(currd),
1270     };
1271     int rc;
1272     unsigned int eflags, ar;
1273
1274     if ( !pv_emul_read_descriptor(regs->cs, curr, &ctxt.cs.base,
1275                                   &ctxt.cs.limit, &ar, 1) ||
1276          !(ar & _SEGMENT_S) ||
1277          !(ar & _SEGMENT_P) ||
1278          !(ar & _SEGMENT_CODE) )
1279         return 0;
1280
1281     /* Mirror virtualized state into EFLAGS. */
1282     ASSERT(regs->eflags & X86_EFLAGS_IF);
1283     if ( vcpu_info(curr, evtchn_upcall_mask) )
1284         regs->eflags &= ~X86_EFLAGS_IF;
1285     else
1286         regs->eflags |= X86_EFLAGS_IF;
1287     ASSERT(!(regs->eflags & X86_EFLAGS_IOPL));
1288     regs->eflags |= curr->arch.pv.iopl;
1289     eflags = regs->eflags;
1290
1291     ctxt.ctxt.addr_size = ar & _SEGMENT_L ? 64 : ar & _SEGMENT_DB ? 32 : 16;
1292     /* Leave zero in ctxt.ctxt.sp_size, as it's not needed. */
1293     rc = x86_emulate(&ctxt.ctxt, &priv_op_ops);
1294
1295     if ( ctxt.io_emul_stub )
1296         unmap_domain_page(ctxt.io_emul_stub);
1297
1298     /*
1299      * Un-mirror virtualized state from EFLAGS.
1300      * Nothing we allow to be emulated can change anything other than the
1301      * arithmetic bits, and the resume flag.
1302      */
1303     ASSERT(!((regs->eflags ^ eflags) &
1304              ~(X86_EFLAGS_RF | X86_EFLAGS_ARITH_MASK)));
1305     regs->eflags |= X86_EFLAGS_IF;
1306     regs->eflags &= ~X86_EFLAGS_IOPL;
1307
1308     switch ( rc )
1309     {
1310     case X86EMUL_OKAY:
1311         if ( ctxt.ctxt.retire.singlestep )
1312             ctxt.bpmatch |= DR_STEP;
1313         if ( ctxt.bpmatch )
1314         {
1315             curr->arch.dr6 |= ctxt.bpmatch | DR_STATUS_RESERVED_ONE;
1316             if ( !(curr->arch.pv.trap_bounce.flags & TBF_EXCEPTION) )
1317                 pv_inject_hw_exception(TRAP_debug, X86_EVENT_NO_EC);
1318         }
1319         /* fall through */
1320     case X86EMUL_RETRY:
1321         return EXCRET_fault_fixed;
1322
1323     case X86EMUL_EXCEPTION:
1324         pv_inject_event(&ctxt.ctxt.event);
1325         return EXCRET_fault_fixed;
1326     }
1327
1328     return 0;
1329 }
1330
1331 /*
1332  * Local variables:
1333  * mode: C
1334  * c-file-style: "BSD"
1335  * c-basic-offset: 4
1336  * tab-width: 4
1337  * indent-tabs-mode: nil
1338  * End:
1339  */